home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / star-1_0.tar / symbols.c < prev    next >
C/C++ Source or Header  |  1991-03-22  |  5KB  |  194 lines

  1. /* symbols.c -- Symbol Table Operations
  2.  
  3.  
  4. This file is part of STAR, the Saturn Macro Assembler.
  5.  
  6.    STAR is not distributed by the Free Software Foundation. Do not ask
  7. them for a copy or how to obtain new releases. Instead, send e-mail to
  8. the address below. STAR is merely covered by the GNU General Public
  9. License.
  10.  
  11. Please send your comments, ideas, and bug reports to
  12. Jan Brittenson <bson@ai.mit.edu>
  13.  
  14. */
  15.  
  16.  
  17. /* Copyright (C) 1990, 1991 Jan Brittenson.
  18.  
  19.    STAR is free software; you can redistribute it and/or modify it
  20. under the terms of the GNU General Public License as published by the
  21. Free Software Foundation; either version 1, or (at your option) any
  22. later version.
  23.  
  24.    STAR is distributed in the hope that it will be useful, but WITHOUT
  25. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  26. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  27. for more details.
  28.  
  29.    You should have received a copy of the GNU General Public License
  30. along with STAR; see the file COPYING. If not, to obtain a copy, write
  31. to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
  32. USA, or send e-mail to bson@ai.mit.edu. */
  33.  
  34.  
  35. /* Notes regarding the hashing algorithm:
  36.  *
  37.  * The key is calculated by sequentially summing up characters while
  38.  * shifting left once after each consequtive character, and finally
  39.  * adding the number of characters. This means that the log2(SYM_NHASH)-1
  40.  * last characters and the length are used in the key. For instance,
  41.  * if SYM_NHASH is set to 8192, this means that the last 12 characters
  42.  * and the string length are used. Some simple tests I've run suggests 
  43.  * this is an almost perfect method for us.
  44.  */
  45.  
  46. #include <stdio.h>
  47. #include "star.h"
  48. #include "symbols.h"
  49.  
  50.  
  51. /* Create symbol table */
  52. SYM_ROOT *sm_open(creator, destructor)
  53.   char *(*creator)();
  54.   void (*destructor)();
  55. {
  56.   SYM_ROOT *stmp;
  57.  
  58.   if(!(stmp = (SYM_ROOT *) (*creator)(sizeof(SYM_ROOT))))
  59.     fatal("Can't allocate %d bytes for symbol table", sizeof(SYM_ROOT));
  60.  
  61.   bclear(stmp, sizeof *stmp);
  62.  
  63.   stmp->sm_create = creator;
  64.   stmp->sm_destr  = destructor;
  65.  
  66.   return(stmp);
  67. }
  68.  
  69.  
  70. /* Hash string - see description above */
  71. hash_symbol(cp)
  72.   register char *cp;
  73. {
  74.   register unsigned sum, nchars;
  75.  
  76.   for(sum = nchars = 0; *cp; cp++, sum <<= 1, nchars++)
  77.     sum += (unsigned char) toupper(*cp);
  78.  
  79.   sum += nchars;
  80.  
  81.   return(sum & (SYM_NHASH-1));
  82. }
  83.  
  84.  
  85. /* Search symbol table for symbol
  86.  *
  87.  * Return pointer to it if found, otherwise NULL.
  88.  */
  89. SYM_NODE *sm_find_sym(sm_root, snam)
  90.   SYM_ROOT *sm_root;
  91.   register char *snam;
  92. {
  93.   register SYM_NODE *ssp;
  94.   
  95.   if(!sm_root)
  96.     return(NULL);
  97.  
  98.  
  99.   /* Traverse symbol table searching for symbol */
  100.   ssp = sm_root->sm_slot[ hash_symbol(snam) ];
  101.  
  102.   while(ssp)
  103.     switch(scmp(snam, ssp->name))
  104.       {
  105.       case -1:    ssp = ssp->slt; break;
  106.       case 1:    ssp = ssp->sgt; break;
  107.       default:    return(ssp);
  108.       }
  109.   
  110.   return(NULL);
  111. }
  112.  
  113.  
  114. /* Duplicate string with given constructor */
  115. static char *sm_strdup(constr, str)
  116.   char *(*constr)(), *str;
  117. {
  118.   char *tmp;
  119.   extern char *strcpy();
  120.  
  121.   if(!(tmp = (*constr)(strlen(str)+1)))
  122.     fatal("Can't allocate %d bytes for symbol name data", strlen(str)+1);
  123.  
  124.   return(strcpy(tmp, str));
  125. }
  126.  
  127.  
  128. /* Enter new symbol into table.
  129.  *
  130.  * Allocates new entry, allocates string space and binds symbol value.
  131.  * The symbol is presumed NOT to exist. Check with 'sm_find_sym()' 
  132.  * before calling this function.
  133.  */
  134. SYM_NODE *sm_enter_sym(sm_root, snam, vl, flg)
  135.   SYM_ROOT *sm_root;
  136.   char *snam;
  137.   struct val vl;
  138.   int flg;
  139. {
  140.   SYM_NODE *ssp, *parent_node;
  141.   char *sp;
  142.   int tmp, hashval;
  143.  
  144.   
  145.   /* Search for place where symbol should be added */
  146.   tmp = 0;
  147.   hashval = hash_symbol(snam);
  148.   ssp = sm_root->sm_slot[hashval];
  149.   parent_node= NULL;
  150.  
  151.   while(ssp)
  152.     switch(tmp = scmp(snam, ssp->name))
  153.       {
  154.       case -1:    parent_node = ssp; ssp = ssp->slt; break;
  155.       case 1:    parent_node = ssp; ssp = ssp->sgt; break;
  156.       case 0:
  157.     {
  158.       sgnwrn("Possible assembler error: symbol `%s' already exists",
  159.          snam);
  160.       return(ssp);
  161.     }
  162.       }
  163.   
  164.   /* Allocate string space */
  165.   sp = sm_strdup(sm_root->sm_create, snam);
  166.   
  167.   for(snam = sp; *snam = toupper(*snam); snam++);
  168.  
  169.   /* Create node */
  170.   if(!(ssp = (SYM_NODE *) (*sm_root->sm_create)(sizeof(SYM_NODE))))
  171.     fatal("Can't allocate %d bytes for symbol table entry", sizeof(SYM_NODE));
  172.   
  173.   /* Update hash table, if necessary, with new root node */
  174.   if(!sm_root->sm_slot[hashval])
  175.     sm_root->sm_slot[hashval] = ssp;
  176.   else
  177.     /* Else hang onto proper leg */
  178.     if(parent_node)
  179.       if(tmp == -1)
  180.     parent_node->slt = ssp;
  181.       else
  182.     parent_node->sgt = ssp;
  183.   
  184.   ssp->slt = ssp->sgt = NULL;
  185.   ssp->vlink = NULL;
  186.   ssp->name = sp;
  187.   ssp->value = vl;
  188.   ssp->flags = flg;
  189.  
  190.   sm_root->nsymbols++;
  191.  
  192.   return(ssp);
  193. }
  194.